package com.ruoyi.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.admin.domain.dto.QuotaTypeDto;
import com.ruoyi.admin.domain.entity.*;
import com.ruoyi.admin.domain.vo.request.atricle.AtriclePageJoinRequest;
import com.ruoyi.admin.domain.vo.request.scheduling.SchedulingAddRequest;
import com.ruoyi.admin.domain.vo.request.scheduling.SchedulingPageJoinRequest;
import com.ruoyi.admin.domain.vo.request.scheduling.SchedulingRequest;
import com.ruoyi.admin.domain.vo.response.atricle.AtriclePageJoinResponse;
import com.ruoyi.admin.domain.vo.response.scheduling.*;
import com.ruoyi.admin.mapper.*;
import com.ruoyi.admin.service.*;
import com.ruoyi.common.api.Result;
import com.ruoyi.common.api.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 排单(Scheduling)Service实现类
 *
 * @author jianhan
 * @date 2022-12-07 15:41:40
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SchedulingServiceImpl extends ServiceImpl<SchedulingMapper, SchedulingModel> implements SchedulingService {

    private static final Logger logger = LoggerFactory.getLogger(SchedulingServiceImpl.class);

    @Resource
    private InventoryMapper inventoryMapper;


    @Resource
    private ProfitMapper profitMapper;



    @Resource
    private WaybillService waybillService;

    @Resource
    private AtricleMapper atricleMapper;

    @Override
    public Result<SchedulingPageJoinResponse> getId(Long schedulingId) {
        SchedulingPageJoinResponse joinById = baseMapper.getJoinById(schedulingId);
        if (joinById != null) {
            return Result.success(joinById);
        }
        return Result.failed(ResultCode.DATA_NOT_EXIST);
    }

    @Override
    public Result<SchedulingPageResponse> page(Page<SchedulingPageJoinRequest> page, SchedulingPageJoinRequest schedulingPageJoinRequest) {
        Page<SchedulingPageJoinResponse> pages = baseMapper.queryPage(page, schedulingPageJoinRequest);
        SchedulingPageResponse schedulingPageResponse = new SchedulingPageResponse(pages);
        return Result.success(schedulingPageResponse);
    }

    @Override
    public Result add(SchedulingAddRequest schedulingAddRequest) {

        List<AtricleModel> atricleModels = atricleMapper.selectList(new QueryWrapper<AtricleModel>().eq("id", schedulingAddRequest.getArticleId()));
        if (atricleModels!=null&&atricleModels.size()>0) {
            AtricleModel atricleModel = atricleModels.get(0);
            List<AtricleModel> atricleModels1 = atricleMapper.selectList(new QueryWrapper<AtricleModel>().eq("article_number", atricleModel.getArticleNumber()).eq("size", schedulingAddRequest.getSize()));
            if (atricleModels1!=null&&atricleModels1.size()>0) {
                AtricleModel atricleModel1 = atricleModels1.get(0);
                schedulingAddRequest.setTotalPrice(schedulingAddRequest.getPrice().multiply(BigDecimal.valueOf(schedulingAddRequest.getNumber())));
                schedulingAddRequest.setOrderNumber(UUID.randomUUID().toString().replace("-", "").substring(0, 12));
                schedulingAddRequest.setStatus("0");
                SchedulingModel schedulingModel = schedulingAddRequest.getSchedulingModel();
                schedulingModel.setArticleId(atricleModel1.getId());
                Boolean result = this.save(schedulingModel);
                if (result) {
                    return Result.success();
                }
            }
        }
        return Result.failed("添加失败");
    }

    @Override
    public Result update(SchedulingAddRequest schedulingAddRequest) {
        List<AtricleModel> atricleModels = atricleMapper.selectList(new QueryWrapper<AtricleModel>().eq("id", schedulingAddRequest.getArticleId()));
        if (atricleModels!=null&&atricleModels.size()>0) {
            AtricleModel atricleModel = atricleModels.get(0);
            List<AtricleModel> atricleModels1 = atricleMapper.selectList(new QueryWrapper<AtricleModel>().eq("article_number", atricleModel.getArticleNumber()).eq("size", schedulingAddRequest.getSize()));
            if (atricleModels1!=null&&atricleModels1.size()>0) {
                AtricleModel atricleModel1 = atricleModels1.get(0);
                schedulingAddRequest.setTotalPrice(schedulingAddRequest.getPrice().multiply(BigDecimal.valueOf(schedulingAddRequest.getNumber())));
                SchedulingModel schedulingModel = schedulingAddRequest.getSchedulingModel();
                schedulingModel.setArticleId(atricleModel1.getId());
                Boolean result = this.updateById(schedulingModel);
                if (result) {
                    return Result.success();
                }
            }
        }
        return Result.failed("更新失败");
    }

    @Override
    public Result<ProfitMonthResponse> getMonthGrossProfit() {
        ProfitMonthResponse profitMonthResponse = new ProfitMonthResponse();
        ProfitMonthResponse thisMonthGrossProfit = baseMapper.thisMonthGrossProfit();
        if (thisMonthGrossProfit!= null) {
            profitMonthResponse.setThisMonth(thisMonthGrossProfit.getThisMonth());
            profitMonthResponse.setThisMonthPercent(thisMonthGrossProfit.getThisMonthPercent());
        }
        ProfitMonthResponse lastMonthGrossProfit = baseMapper.lastMonthGrossProfit();
        if (lastMonthGrossProfit!=null) {
            profitMonthResponse.setLastMonth(lastMonthGrossProfit.getLastMonth());
            profitMonthResponse.setLastMonthPercent(lastMonthGrossProfit.getLastMonthPercent());
        }
        ProfitMonthResponse thisYearGrossProfit = baseMapper.thisYearGrossProfit();
        if (thisYearGrossProfit!=null) {
            profitMonthResponse.setThisYear(thisYearGrossProfit.getThisYear());
            profitMonthResponse.setThisYearPercent(thisYearGrossProfit.getThisYearPercent());
        }
        ProfitMonthResponse thisQuarterGrossProfit = baseMapper.thisQuarterGrossProfit();
        if (thisQuarterGrossProfit!=null) {
            profitMonthResponse.setThisQuarter(thisQuarterGrossProfit.getThisQuarter());
            profitMonthResponse.setThisQuarterPercent(thisQuarterGrossProfit.getThisQuarterPercent());
        }

        return Result.success(profitMonthResponse);
    }

    @Override
    public Result<SalesQuotaResponse> getQuota(){
        SalesQuotaResponse salesQuotaResponse = new SalesQuotaResponse();
        List<QuotaTypeDto> quotaTypeTodayList = baseMapper.getQuotaTypeToday();
        for (QuotaTypeDto quotaTypeToday : quotaTypeTodayList) {
            if (quotaTypeToday.getType().equals("1")){
                salesQuotaResponse.setDayPurchaseQuota(quotaTypeToday.getQuota());
            }else if (quotaTypeToday.getType().equals("2")){
                salesQuotaResponse.setDaySalesQuota(quotaTypeToday.getQuota());
            }
        }
        List<QuotaTypeDto> quotaTypeMonths = baseMapper.getQuotaTypeMonth();
        for (QuotaTypeDto quotaTypeMonth : quotaTypeMonths) {
            if (quotaTypeMonth.getType().equals("1")){
                salesQuotaResponse.setMonthPurchaseQuota(quotaTypeMonth.getQuota());
            }else if (quotaTypeMonth.getType().equals("2")){
                salesQuotaResponse.setMonthSalesQuota(quotaTypeMonth.getQuota());
            }
        }
        return Result.success(salesQuotaResponse);
    }


    @Override
    @Transactional
    public Result updateByStatus(SchedulingRequest schedulingRequest) {
        List<SchedulingModel> schedulingModels = baseMapper.selectList(new QueryWrapper<SchedulingModel>().in("id", Arrays.asList(schedulingRequest.getId().split(",")).stream().collect(Collectors.toList())));
        if (schedulingModels.size() > 0 && schedulingModels != null) {
            for (SchedulingModel schedulingModel : schedulingModels) {
                InventoryModel inventoryModel =new InventoryModel();
                //现在要改为已处理
                if (schedulingRequest.getStatus().equals("1")) {
                    //原先是正在处理中或者撤销
                    if (schedulingModel.getStatus().equals("0") || schedulingModel.getStatus().equals("2")) {
                        List<InventoryModel> inventoryModels = inventoryMapper.selectList(new QueryWrapper<InventoryModel>().eq("atricle_id", schedulingModel.getArticleId()));
                        Long inventoryId = 0L;
                        //修改 库存
                        if (inventoryModels.size() > 0 && inventoryModels != null) {
                            inventoryModel = inventoryModels.get(0);
                            if (schedulingModel.getType().equals("1")) {
                                inventoryModel.setNumber(inventoryModel.getNumber() + schedulingModel.getNumber());
                                inventoryModel.setTotalPrice(inventoryModel.getTotalPrice().add(schedulingModel.getTotalPrice()));
                            } else if (schedulingModel.getType().equals("2")) {
                                inventoryModel.setNumber(inventoryModel.getNumber() - schedulingModel.getNumber());
                                inventoryModel.setTotalPrice(inventoryModel.getTotalPrice().subtract(inventoryModel.getPrice().multiply(new BigDecimal(schedulingModel.getNumber()))));
                            }
                            inventoryModel.setPrice(inventoryModel.getTotalPrice().divide(new BigDecimal(inventoryModel.getNumber()), BigDecimal.ROUND_CEILING));
                            inventoryMapper.updateById(inventoryModel);
                            inventoryId = inventoryModel.getId();
                        } else {
                            AtriclePageJoinRequest atriclePageJoinRequest = new AtriclePageJoinRequest();
                            atriclePageJoinRequest.setId(schedulingModel.getArticleId());
                            List<AtriclePageJoinResponse> atriclePageJoinResponses = atricleMapper.selectListA(atriclePageJoinRequest);
                            if (atriclePageJoinResponses != null && atriclePageJoinResponses.size() > 0) {
                                if (schedulingModel.getType().equals("1")) {
                                    AtriclePageJoinResponse atriclePageJoinResponse = atriclePageJoinResponses.get(0);
                                    inventoryModel.setSize(schedulingModel.getSize());
                                    inventoryModel.setAtricleId(schedulingModel.getArticleId());
                                    inventoryModel.setBrand(atriclePageJoinResponse.getBrand());
                                    inventoryModel.setAtricleNumber(atriclePageJoinResponse.getArticleNumber());
                                    inventoryModel.setNumber(schedulingModel.getNumber());
                                    inventoryModel.setTotalPrice(schedulingModel.getTotalPrice());
                                    inventoryModel.setPrice(schedulingModel.getPrice());
                                    inventoryMapper.insert(inventoryModel);
                                    inventoryId = inventoryModel.getId();
                                } else {
                                    return Result.failed("id为" + schedulingModel.getId() + "订单编号为:" + schedulingModel.getOrderNumber() + "的排单没有库存");
                                }
                            }
                        }
                        //修改报表
                        List<ProfitModel> profitModels = profitMapper.selectList(new QueryWrapper<ProfitModel>().eq("article_id", schedulingModel.getArticleId()));

                        if (profitModels.size() > 0 && profitModels != null) {
                            ProfitModel profitModel = profitModels.get(0);
                            if (schedulingModel.getType().equals("1")) {
                                //采购
                                profitModel.setInputAmount(profitModel.getInputAmount().add(schedulingModel.getTotalPrice()));
                            } else if (schedulingModel.getType().equals("2")) {
                                //销售
                                profitModel.setOutputAmount(profitModel.getOutputAmount().add(schedulingModel.getTotalPrice()));
                                profitModel.setGrossMargin(profitModel.getGrossMargin().add(schedulingModel.getTotalPrice().subtract(inventoryModel.getPrice().multiply(new BigDecimal(schedulingModel.getNumber())))));
                            }
                            profitMapper.updateById(profitModel);
                        } else {
                            ProfitModel profitModel = new ProfitModel();
                            profitModel.setArticleId(schedulingModel.getArticleId());
                            profitModel.setInventoryId(inventoryId);
                            if (schedulingModel.getType().equals("1")) {
                                profitModel.setInputAmount(schedulingModel.getTotalPrice());
                            } else if (schedulingModel.getType().equals("2")) {
                                profitModel.setOutputAmount(schedulingModel.getTotalPrice());
                                profitModel.setGrossMargin(schedulingModel.getTotalPrice().subtract(inventoryModel.getPrice().multiply(new BigDecimal(inventoryModel.getNumber()))));
                            }
                            profitMapper.insert(profitModel);
                        }
                        schedulingModel.setStatus(schedulingRequest.getStatus());
                    }
                } else if (schedulingRequest.getStatus().equals("2")) {
                    //现在要改为已撤销
                    if (schedulingModel.getStatus().equals("0")) {
                        //原先是正在处理中
                        schedulingModel.setStatus(schedulingRequest.getStatus());
                    } else if (schedulingModel.getStatus().equals("1")) {
                        //原先是已处理
                        List<InventoryModel> inventoryModels = inventoryMapper.selectList(new QueryWrapper<InventoryModel>().eq("atricle_id", schedulingModel.getArticleId()));
                        if (inventoryModels.size() > 0 && inventoryModels != null) {
                            inventoryModel = inventoryModels.get(0);
                            if (schedulingModel.getType().equals("1")) {
                                inventoryModel.setNumber(inventoryModel.getNumber() - schedulingModel.getNumber());
                                inventoryModel.setTotalPrice(inventoryModel.getTotalPrice().subtract(schedulingModel.getTotalPrice()));
                            } else if (schedulingModel.getType().equals("2")) {
                                inventoryModel.setNumber(inventoryModel.getNumber() + schedulingModel.getNumber());
                                inventoryModel.setTotalPrice(inventoryModel.getTotalPrice().add(inventoryModel.getPrice().multiply(new BigDecimal(schedulingModel.getNumber()))));
                            }
                            if (inventoryModel.getNumber()!=0L){
                                inventoryModel.setPrice(inventoryModel.getTotalPrice().divide(new BigDecimal(inventoryModel.getNumber()), BigDecimal.ROUND_CEILING));
                            }else {
                                inventoryModel.setPrice(BigDecimal.ZERO);
                            }
                            inventoryMapper.updateById(inventoryModel);
                        }
                        List<ProfitModel> profitModels = profitMapper.selectList(new QueryWrapper<ProfitModel>().eq("article_id", schedulingModel.getArticleId()));
                        if (profitModels.size() > 0 && profitModels != null) {
                            ProfitModel profitModel = profitModels.get(0);
                            if (schedulingModel.getType().equals("1")) {
                                //采购
                                profitModel.setInputAmount(profitModel.getInputAmount().subtract(schedulingModel.getTotalPrice()));
                            } else if (schedulingModel.getType().equals("2")) {
                                //销售
                                profitModel.setOutputAmount(profitModel.getOutputAmount().subtract(schedulingModel.getTotalPrice()));
                                profitModel.setGrossMargin(profitModel.getGrossMargin().subtract((schedulingModel.getPrice().subtract(inventoryModel.getPrice())).multiply(new BigDecimal(schedulingModel.getNumber()))));
                            }
                            profitMapper.updateById(profitModel);
                        }
                        schedulingModel.setStatus(schedulingRequest.getStatus());
                    }
                } else if (schedulingRequest.getStatus().equals("0")) {
                    //现在要改为未处理
                    if (schedulingModel.getStatus().equals("1")) {
                        //原先是已处理
                        List<InventoryModel> inventoryModels = inventoryMapper.selectList(new QueryWrapper<InventoryModel>().eq("atricle_id", schedulingModel.getArticleId()));
                        if (inventoryModels.size() > 0 && inventoryModels != null) {
                            inventoryModel = inventoryModels.get(0);
                            if (schedulingModel.getType().equals("1")) {
                                inventoryModel.setNumber(inventoryModel.getNumber() - schedulingModel.getNumber());
                                inventoryModel.setTotalPrice(inventoryModel.getTotalPrice().subtract(schedulingModel.getTotalPrice()));
                            } else if (schedulingModel.getType().equals("2")) {
                                inventoryModel.setNumber(inventoryModel.getNumber() + schedulingModel.getNumber());
                                inventoryModel.setTotalPrice(inventoryModel.getTotalPrice().add(schedulingModel.getTotalPrice()));
                            }
                            if (inventoryModel.getNumber()!=0L){
                                inventoryModel.setPrice(inventoryModel.getTotalPrice().divide( new BigDecimal(inventoryModel.getNumber()), BigDecimal.ROUND_CEILING));
                            }else {
                                inventoryModel.setPrice(BigDecimal.ZERO);
                            }
                            inventoryMapper.updateById(inventoryModel);
                        }
                        List<ProfitModel> profitModels = profitMapper.selectList(new QueryWrapper<ProfitModel>().eq("article_id", schedulingModel.getArticleId()));
                        if (profitModels.size() > 0 && profitModels != null) {
                            ProfitModel profitModel = profitModels.get(0);

                            if (schedulingModel.getType().equals("1")) {
                                //采购
                                profitModel.setInputAmount(profitModel.getInputAmount().subtract(schedulingModel.getTotalPrice()));
                            } else if (schedulingModel.getType().equals("2")) {
                                //销售
                                profitModel.setOutputAmount(profitModel.getOutputAmount().subtract(schedulingModel.getTotalPrice()));
                                profitModel.setGrossMargin(profitModel.getGrossMargin().subtract(inventoryModel.getPrice().multiply(new BigDecimal(inventoryModel.getNumber()))));
                            }
                            profitMapper.updateById(profitModel);
                        }
                    } else if (schedulingModel.getStatus().equals("2")) {
                        schedulingModel.setStatus(schedulingRequest.getStatus());
                    }
                }
            }
            this.updateBatchById(schedulingModels);
            WaybillModel waybillModel = new WaybillModel();
            waybillModel.setType(schedulingModels.get(0).getType());
            waybillModel.setFreight(schedulingRequest.getFreight());
            waybillModel.setSchedulingIds(schedulingRequest.getId());
            waybillModel.setWaybillNumber(schedulingRequest.getWaybillNumber());
            waybillService.save(waybillModel);
            return Result.success("修改成功");
        }
        return Result.failed("更新失败");
    }

    @Override
    public Result delete(Long schedulingId) {
        Boolean result = this.removeById(schedulingId);
        return Result.judge(result);

    }

    @Override
    public Result<List<SupplierQuotaResponse>> getSupplierQuota() {
        List<SupplierQuotaResponse> supplierQuota = baseMapper.getSupplierQuota();
        return Result.success(supplierQuota);
    }

    @Override
    public Result<List<HotListResponse>> getHotList() {
        return Result.success(baseMapper.getHotList());
    }

    @Override
    public Result<PendingResponse> getPending() {
        List<SchedulingModel> todayPending = baseMapper.getTodayPending();
        List<SchedulingModel> yesterdayPending = baseMapper.getYesterdayPending();
        PendingResponse pendingResponse = new PendingResponse();
        Integer yesterdayPurchase = 0;//昨天待处理采购
        Integer yesterdaySale = 0;//昨天待处理销售
        Integer todayPurchase = 0;//今天待处理采购
        Integer todaySale = 0;//今天待处理销售
        Integer todaySaleRa = 0;//今天已处理销售
        Integer todayPurchaseRa = 0;//今天已处理采购
        for (SchedulingModel schedulingModel : todayPending) {
            //待处理
            if (schedulingModel.getStatus().equals("0")) {
                //采购
                if (schedulingModel.getType().equals("1")) {
                    todayPurchase ++;
                } else {
                    //销售
                    todaySale ++;
                }
            }else {
                //已处理
                if (schedulingModel.getType().equals("1")) {
                    todayPurchaseRa ++;
                }else {
                    todaySaleRa ++;
                }
            }
        }
        for (SchedulingModel schedulingModel : yesterdayPending) {
            if (schedulingModel.getStatus().equals("0")){
                if (schedulingModel.getType().equals("1")) {
                    yesterdaySale ++;
                } else {
                    yesterdayPurchase ++;
                }
            }
        }
        pendingResponse.setTodayPurchase(todayPurchase);
        pendingResponse.setTodaySale(todaySale);
        pendingResponse.setYesterdayPurchase(yesterdayPurchase);
        pendingResponse.setYesterdaySale(yesterdaySale);
        //除法算已处理比例
        if (todaySaleRa!=0){
            pendingResponse.setSaleRatio(todaySaleRa/(todaySale+todaySaleRa));
        }else {
            pendingResponse.setSaleRatio(1);
        }
        if (todayPurchaseRa!=0){
            pendingResponse.setPurchaseRatio(todayPurchaseRa/(todayPurchaseRa+todayPurchase));
        }else {
            pendingResponse.setPurchaseRatio(1);
        }
        return Result.success(pendingResponse);
    }

    @Override
    public Result<List<DayTotalResponse>> getDayTotal() {
        return  Result.success(baseMapper.getTotalGroupByDay());
    }

    private QueryWrapper<SchedulingModel> queryWrapper(SchedulingModel schedulingModel) {
        QueryWrapper<SchedulingModel> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(schedulingModel.getOrderNumber())) {
            queryWrapper.like("order_number", schedulingModel.getOrderNumber());
        }
        if (StringUtils.isNotEmpty(schedulingModel.getType())) {
            queryWrapper.eq("type", schedulingModel.getType());
        }
        if (StringUtils.isNotEmpty(schedulingModel.getStatus())) {
            queryWrapper.eq("status", schedulingModel.getStatus());
        }
        /*
           写搜索条件
        */
        queryWrapper.orderByDesc("id");
        return queryWrapper;
    }

}
